package com.baitiaojun.video.websocket;

import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.util.SpringContextUtil;
import com.baitiaojun.api.util.TokenUtil;
import com.baitiaojun.video.support.RedisSupport;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @类名 WebsocketServer
 * @描述 TODO 废弃
 * @作者 白条君
 * @创建日期 2023/1/28 16:04
 * @版本 1.0
 */
@Getter
@Slf4j
@Component
@ServerEndpoint("/upload-process/{token}")
public class WebsocketServer {

    public static final ConcurrentHashMap<Long, WebsocketServer> websocketServerMap = new ConcurrentHashMap<>();

    private Session session;

    private Long userId;

    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) throws Exception {
        this.session = session;
        String accessToken = token;
        StringBuilder builder = new StringBuilder();
        if (!TokenUtil.isExpiresToken(accessToken)) {
            accessToken = this.refreshToken(token);
            builder.append("token:").append(accessToken).append("\n");
        }
        userId = TokenUtil.verifyToken(accessToken);
        if (ObjectUtils.isNotEmpty(userId)) {
            if (websocketServerMap.containsKey(userId)) {
                websocketServerMap.remove(userId);
                websocketServerMap.put(userId, this);
            } else {
                websocketServerMap.put(userId, this);
            }
        }
        builder.append("status:").append(ConstantUtil.WEB_SOCKET_OPEN_STATUS);
        this.sendMsg(builder.toString());
    }

    private void sendMsg(String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        this.sendMsg(message);
    }

    @OnClose
    public void closeConnection() {
        websocketServerMap.remove(userId);
        log.info("连接关闭");
    }

    private String refreshToken(String accessToken) throws Exception {
        RedisSupport redisSupport = SpringContextUtil.getBean(RedisSupport.class);
        String refreshToken = String.valueOf(redisSupport.getHash(accessToken, ConstantUtil.Field.REFRESH_TOKEN.getKey()));
        if (TokenUtil.isExpiresToken(refreshToken)) {
            Map<String, Object> values = redisSupport.hash().entries(accessToken);
            redisSupport.delete(accessToken);
            accessToken = TokenUtil.generateToken(TokenUtil.verifyToken(refreshToken), ConstantUtil.TokenType.ACCESS);
            redisSupport.hash().putAll(accessToken, values);
            redisSupport.getRedisTemplate().expire(accessToken, ConstantUtil.REFRESH_TOKEN_TIMEOUT, TimeUnit.DAYS);
        }
        return accessToken;
    }
}
